#include "Dri_UART.h"

/**
 * @brief 发送单个字节状态,(默认发送成功,这样第一个数据可以进入)
 *
 */
static bit S_TRANSMIT_BYTE_STATE = 1;

/**
 * @brief 接受单个字节状态,默认没有接收成功
 *
 */
static bit S_RECEPTION_BYTE_STATE = 0;

/**
 * @brief 接受字符串状态,默认没有接收成功
 *
 */
static bit S_RECEPTION_STRING_STATE = 0;

/**
 * @brief 接受字符串数组
 *
 */
static u8 S_RECEPTION_STRING_ARRAY[20];

/**
 * @brief 接受字符串数组长度
 *
 */
static u8 S_RECEPTION_STRING_ARRAY_INDEX;

/**
 * @brief 初始化 uart
 *
 */
void Dri_UART_Init()
{

    // 1. 设置UART模式,8位UART,波特率可变
    SM1 = 1;
    SM0 = 0;

    // 2.设置是否2分频
    PCON &= 0X7F;

    // 3. 定时器1,设置 8位自动从装载设置= M1M0 = 10, C/T = 0(定时器),
    TMOD &= 0X7F;
    TMOD |= 0X2F;
    // 4. 设置波特率(9200) = 指令周期(11059200) / 32/溢出率(x) --> 指令周期(11059200/12)  = 波特率(9200) *  32 * 溢出率(x)
    // 4.1 tl1 = (255+1) - 溢出率(3)
    TL1 = 253;
    TH1 = 253;
    // 4.2 开始计算
    TR1 = 1;

    // 4. 设置串口接收
    REN = 1;
    // 4.1 设置是否检查停止位(默认= 不需要 = 0)
    SM0 = 0;

    // 配置串口优先级,这样就不会被定时器打断
    PS = 1;
    IPH &= 0XEF;
    IPH |= 0X10;
    // 配置开启中断
    EA = 1;
    ES = 1;
}

/**
 * @brief 发送单个字节
 *
 * @param byte 发送数据
 */
void Dri_UART_Transmit_Byte(u8 byte)
{
    // 在发送则等待
    while (S_TRANSMIT_BYTE_STATE == 0) {
    }

    SBUF = byte;
    // 添加好数据,等待发送
    S_TRANSMIT_BYTE_STATE = 0;
}

/**
 * @brief 发送字符串
 *
 * @param byte 发送数据
 */
void Dri_UART_Transmit_String(u8 *byte)
{
    u8 i = 0;
    // 因为字符串最后一位用 \0 结尾
    while (byte[i]) {
        Dri_UART_Transmit_Byte(byte[i]);
        i++;
    }
}

/**
 * @brief 接受单个字节
 *
 * @param byte 接受字节
 * @return bit
 */
bit Dri_UART_Reception_Byte(u8 *byte)
{
    if (S_RECEPTION_BYTE_STATE == 1) {
        *byte                  = SBUF;
        S_RECEPTION_BYTE_STATE = 0;
        return 1;
    }
    return 0;
}

/**
 * @brief 接受单个字节 用于定时器
 *
 */
void Dri_UART_Reception_Byte_Timer()
{
    u8 res_data;
    bit isOk = Dri_UART_Reception_Byte(&res_data);
    if (isOk) {
        if (res_data == 'A' || res_data == 'a') {
            P0 = 0X00;
            Dri_UART_Transmit_String("ok!!!!");
        } else {
            P0 = ~P0;
            Dri_UART_Transmit_String("no!!!!");
        }
    }
}

/**
 * @brief 接受字符串数据
 *
 * @param byte 字符串
 * @return bit
 */
bit Dri_UART_Reception_String(u8 *byte)
{
    u8 i;
    // 没有数据则返回
    if (S_RECEPTION_STRING_STATE == 0) {
        return 0;
    }

    // 迭代获取数据
    for (i = 0; i < S_RECEPTION_STRING_ARRAY_INDEX; i++) {
        byte[i] = S_RECEPTION_STRING_ARRAY[i];
    }
    // 要带一个 \0,这个式C语言的规则不然会报错
    byte[S_RECEPTION_STRING_ARRAY_INDEX] = '\0';
    S_RECEPTION_STRING_ARRAY_INDEX       = 0;
    S_RECEPTION_STRING_STATE             = 0;
    return 1;
}

/**
 * @brief 中断接受函数
 *
 */
void Dri_UART_Hader() interrupt 4
{
    u8 dataByte;
    // 读取到数据
    if (RI == 1) {

        dataByte = SBUF;
        if (dataByte != '\n' && S_RECEPTION_STRING_ARRAY_INDEX < 19) {
            S_RECEPTION_STRING_ARRAY[S_RECEPTION_STRING_ARRAY_INDEX] = dataByte;
            S_RECEPTION_STRING_ARRAY_INDEX++;
        } else {
            S_RECEPTION_STRING_STATE = 1;
        }

        // 单个字节使用
        S_RECEPTION_BYTE_STATE = 1;

        RI = 0;
    }

    // 发送数据成功
    if (TI == 1) {
        S_TRANSMIT_BYTE_STATE = 1;
        // 手动复位
        TI = 0;
    }
}
